import zipfile
import os
import shutil


def remove_file(file_path):
    """
    Удаляет папки и файлы
    :param file_path: путь к удаляемому файлу
    :return:
    """
    if os.path.basename(file_path) == "Journals_3D" or os.path.basename(file_path) == "Journals":
        shutil.rmtree(file_path)
    else:
        os.remove(file_path)


def unpack_zip(archive, dst):
    """
    функция распаковки архива
    :param dst: путь распаковки архива
    :param archive: путь архива
    :return:
    """
    with zipfile.ZipFile(archive, 'r') as zp:
        zp.extractall(dst)


def unpack_folder(folder_path: str, dst) -> None:
    """
    ищет zip файлы и разархивирует их
    :param dst: путь распаковки архива
    :param folder_path: путь папки
    :return:
    """
    print(folder_path)
    for i_name in os.listdir(folder_path):
        if zipfile.is_zipfile(os.path.join(folder_path, i_name)):
            if i_name.startswith('TestResults'):
                unpack_zip(os.path.join(folder_path, i_name), dst)
                with zipfile.ZipFile(os.path.join(folder_path, i_name)) as zp:
                    for i_file in zp.namelist():
                        unpack_folder(os.path.join(dst, i_file.split('/')[0]), dst=os.path.join(dst, i_file.split('/')[0]))
            else:
                unpack_zip(os.path.join(folder_path, i_name), os.path.join(dst, i_name).replace('.zip', ''))
                unpack_folder(os.path.join(dst, i_name).replace('zip', ''), dst=os.path.join(dst, i_name).replace('zip', ''))
        elif os.path.isdir(os.path.join(folder_path, i_name)) and (i_name != 'Journals_3D' and i_name != 'Journals'):
            unpack_folder(os.path.join(folder_path, i_name), dst=os.path.join(dst, i_name).replace('.zip', ''))


def remove_garbage_files(folder_path, file_handler=lambda path: remove_file(path)):
    """
    Функция, удаляющая файлы, не удовлетворяющие условиям
    :param file_handler: функция, отвечающая за действия над искомыми файлами
    :param folder_path: путь папки с файлами
    :return:
    """
    for i_name in os.listdir(folder_path):
        if i_name == 'Journals_3D' or i_name == 'Journals':
            file_handler(os.path.join(folder_path, i_name))
        elif not(os.path.isdir(os.path.join(folder_path, i_name)))\
                and ('cmake' not in i_name and i_name != 'utest.log' and i_name != 'results.json'):
            file_handler(os.path.join(folder_path, i_name))
        elif os.path.isdir(os.path.join(folder_path, i_name)):
            remove_garbage_files(os.path.join(folder_path, i_name), file_handler=lambda path: remove_file(path))


def prepare_data(folder_path, dst):
    """
    Функция, подготавливающая данные к последующему анализу
    :param dst: путь распаковки архива
    :param folder_path: путь к директории
    :return:
    """
    unpack_folder(folder_path, dst)
    remove_garbage_files(dst)


if __name__ == '__main__':
    test_path = r'C:\Users\anyca\Desktop\Data\TestResults'
    dst = r'C:\Users\anyca\Desktop\TestResults_Unpack'
    prepare_data(test_path, dst)
